/**
 * 图表数据处理工具函数
 */

import { ChartDataPoint, ColumnDefinition, ChartData, ChartAxisConfig } from '../components/charts/types';

/**
 * 尝试将值转换为数字
 */
export const tryConvertToNumber = (value: any): number | null => {
  if (value === null || value === undefined) return null;
  if (typeof value === 'number') {
    return isNaN(value) ? null : value;
  }
  const str = String(value).trim();
  if (str === '' || str === 'NaN' || str === 'null' || str === 'undefined') return null;
  const num = parseFloat(str);
  return isNaN(num) ? null : num;
};

/**
 * 检查列是否可以转换为数值列
 * @param colName 列名
 * @param data 数据数组
 * @param threshold 可转换数据的阈值比例，默认0.7（70%）
 */
export const isNumericColumn = (
  colName: string,
  data: ChartDataPoint[],
  threshold: number = 0.7
): boolean => {
  if (data.length === 0) return false;
  let convertibleCount = 0;
  for (const row of data) {
    const value = tryConvertToNumber(row[colName]);
    if (value !== null) {
      convertibleCount++;
    }
  }
  return convertibleCount / data.length >= threshold;
};

/**
 * 检测数值类型的列
 */
export const isTypeNumeric = (type: string): boolean => {
  const numericTypes = ['float', 'double', 'integer', 'int64', 'int', 'number', 'numeric'];
  return numericTypes.includes(type.toLowerCase());
};

/**
 * 自动检测数值列
 */
export const detectNumericColumns = (
  columns: ColumnDefinition[],
  data: ChartDataPoint[],
  excludeColumns: string[] = []
): string[] => {
  return columns
    .filter(col => !excludeColumns.includes(col.name))
    .filter(col => {
      // 先检查类型
      if (isTypeNumeric(col.type)) return true;
      // 如果类型不明确，尝试转换数据
      return isNumericColumn(col.name, data);
    })
    .map(col => col.name);
};

/**
 * 提取列的数值数据
 */
export const extractNumericValues = (
  data: ChartDataPoint[],
  columnName: string,
  defaultValue: number = 0
): number[] => {
  return data.map(row => {
    const num = tryConvertToNumber(row[columnName]);
    return num !== null ? num : defaultValue;
  });
};

/**
 * 提取标签数据（X轴）
 */
export const extractLabels = (
  data: ChartDataPoint[],
  columnName: string
): string[] => {
  return data.map(row => {
    const value = row[columnName];
    return value !== null && value !== undefined ? String(value) : '';
  });
};

/**
 * 获取默认图表颜色
 */
export const getChartColors = (index: number, alpha: number = 0.8): { bg: string; border: string } => {
  const colors = [
    'rgba(54, 162, 235, ',
    'rgba(255, 99, 132, ',
    'rgba(75, 192, 192, ',
    'rgba(255, 206, 86, ',
    'rgba(153, 102, 255, ',
    'rgba(255, 159, 64, ',
    'rgba(199, 199, 199, ',
    'rgba(83, 102, 255, ',
    'rgba(255, 99, 255, ',
    'rgba(99, 255, 132, ',
  ];

  const colorBase = colors[index % colors.length];
  return {
    bg: colorBase + alpha + ')',
    border: colorBase + '1)',
  };
};

/**
 * 准备图表数据
 * 支持多组数据和多列
 */
export const prepareChartData = (
  data: ChartDataPoint[],
  columns: ColumnDefinition[],
  config?: ChartAxisConfig
): ChartData | null => {
  if (!data || data.length === 0 || !columns || columns.length === 0) {
    return null;
  }

  // X轴：使用配置或第一列
  const xAxis = config?.xAxis || columns[0]?.name;
  if (!xAxis) {
    return null;
  }

  // Y轴：使用配置或自动检测
  let yAxis: string[] = [];
  if (config?.yAxis && config.yAxis.length > 0) {
    yAxis = config.yAxis;
  } else {
    yAxis = detectNumericColumns(columns, data, [xAxis]);
  }

  // 验证Y轴列是否真的可以转换
  const validYAxis = yAxis.filter(colName => {
    return isNumericColumn(colName, data, 0.3); // 降低阈值，至少30%可转换即可
  });

  if (validYAxis.length === 0) {
    return null;
  }

  // 生成标签（X轴数据）
  const labels = extractLabels(data, xAxis);

  // 生成数据集（Y轴数据）
  const datasets = validYAxis.map((colName, index) => {
    const values = extractNumericValues(data, colName, 0);
    const colors = getChartColors(index);

    return {
      label: colName,
      data: values,
      backgroundColor: colors.bg,
      borderColor: colors.border,
      borderWidth: 2,
    };
  });

  return {
    labels,
    datasets,
  };
};

/**
 * 合并多组数据为图表数据
 * 用于对比多个实验的数据
 */
export const mergeChartData = (
  datasets: Array<{
    data: ChartDataPoint[];
    columns: ColumnDefinition[];
    config?: ChartAxisConfig;
    labelPrefix?: string;
  }>
): ChartData | null => {
  if (datasets.length === 0) return null;

  // 使用第一组数据的配置
  const firstDataset = datasets[0];
  const xAxis = firstDataset.config?.xAxis || firstDataset.columns[0]?.name;
  
  if (!xAxis) return null;

  // 收集所有可能的Y轴列
  const allYColumns = new Set<string>();
  datasets.forEach(ds => {
    const yCols = ds.config?.yAxis || detectNumericColumns(ds.columns, ds.data, [xAxis]);
    yCols.forEach(col => allYColumns.add(col));
  });

  if (allYColumns.size === 0) return null;

  // 合并标签（使用第一组数据的标签）
  const labels = extractLabels(firstDataset.data, xAxis);

  // 为每组数据创建数据集
  const chartDatasets: any[] = [];
  const allYColumnsArray = Array.from(allYColumns);
  datasets.forEach((dataset, dsIndex) => {
    const prefix = dataset.labelPrefix || `数据集 ${dsIndex + 1}`;
    
    allYColumnsArray.forEach((colName, colIndex) => {
      // 检查该数据集是否包含此列
      const hasColumn = dataset.columns.some(c => c.name === colName);
      if (!hasColumn) return;

      const values = extractNumericValues(dataset.data, colName, 0);
      const colors = getChartColors(dsIndex * allYColumnsArray.length + colIndex);

      chartDatasets.push({
        label: `${prefix} - ${colName}`,
        data: values,
        backgroundColor: colors.bg,
        borderColor: colors.border,
        borderWidth: 2,
      });
    });
  });

  return {
    labels,
    datasets: chartDatasets,
  };
};
